﻿#include "HorizontalPositionerWidget.h"

void RHorizontalPositionerWidget::CalculateChildrenPresentPositionAndSize()
{
    ArrangeChildren();
}

float RHorizontalPositionerWidget::CalculateContentWidth()
{
    return PresentLength;
}

void RHorizontalPositionerWidget::ArrangeChildren()
{
    auto _Align=Align.Get();
    float _Spacing=Spacing.Get();

    TVector<float> ChildWidths;
    for(int32_t i=0;i<SubWidgets.Num();++i)
    {
        auto& Child=SubWidgets[i];
        ChildWidths.Add(Child->Width.Get());
    }

    //计算子控件的总长度
    PresentLength=.0f;
    for(int32_t i=0;i<ChildWidths.Num();++i)
    {
        PresentLength+=ChildWidths[i]+_Spacing;
    }
    if(ChildWidths.Num()>0)
    {
        PresentLength-=_Spacing;
    }


    //隐藏超出的子控件
    auto _HideMethod=HideMethod.Get();
    switch(_HideMethod)
    {
        case EHorizontalPositionerHideMethod::NevenHide:
        {
            MinVisibleSubWidgetIndex=0;
            MaxVisibleSubWidgetIndex=SubWidgets.Num()-1;
            break;
        }
        case EHorizontalPositionerHideMethod::HideLeft:
        {
            float _Width=PresentSize.X/GetAccumulatedScale().X;
            float Diff=PresentLength-_Width;
            
            if(Diff>0)
            {
                MinVisibleSubWidgetIndex=SubWidgets.Num();
                for(int32_t i=0;i<SubWidgets.Num();++i)
                {
                    if(Diff<=0)
                    {
                        MinVisibleSubWidgetIndex=i;
                        break;
                    }

                    auto& Child=SubWidgets[i];
                    Diff-=ChildWidths[i]+_Spacing;

                }
                MaxVisibleSubWidgetIndex=
                    CMath::Max(MinVisibleSubWidgetIndex,SubWidgets.Num()-1);
            
            }
            else
            {
                MinVisibleSubWidgetIndex=0;
                MaxVisibleSubWidgetIndex=SubWidgets.Num()-1;
            }
            break;

        }

        case EHorizontalPositionerHideMethod::HideRight:
        {
            float _Width=PresentSize.X/GetAccumulatedScale().X;
            float Diff=PresentLength-_Width;
            if(Diff>0)
            {
                MaxVisibleSubWidgetIndex=-1;
                for(int32_t i=SubWidgets.Num()-1;i>=0;--i)
                {
                    if(Diff<=0)
                    {
                        MaxVisibleSubWidgetIndex=i;
                        break;
                    }

                    auto& Child=SubWidgets[i];
                    Diff-=ChildWidths[i]+_Spacing;
                }
                MinVisibleSubWidgetIndex=0;
            }
            else
            {
                MinVisibleSubWidgetIndex=0;
                MaxVisibleSubWidgetIndex=SubWidgets.Num()-1;
            }
            break;
        }
    
        default:
        {
            //不应执行到这里
            assert(false);
        }
    }

    HasVisibleSubWidget=MinVisibleSubWidgetIndex<SubWidgets.Num()&&
        MaxVisibleSubWidgetIndex>=0;

    if(HasVisibleSubWidget)
    {
        //存在可见的子控件
        switch(_Align)
        {
            case EHorizontalPositionerAlign::Left:
            {
                float NextWidgetX=.0f;
                for(int32_t i=MinVisibleSubWidgetIndex;i<=MaxVisibleSubWidgetIndex;++i)
                {
                    auto& Child=SubWidgets[i];
                    Child->X=NextWidgetX;
                    NextWidgetX+=Child->Width.Get()+_Spacing;
                }
                break;
            }

            case EHorizontalPositionerAlign::Right:
            {
                float SelfWith=PresentSize.X/GetAccumulatedScale().X;
                float NextWidgetX=SelfWith;

                for(int32_t i=MaxVisibleSubWidgetIndex;i>=MinVisibleSubWidgetIndex;--i)
                {
                    auto& Child=SubWidgets[i];
                    NextWidgetX-=Child->Width.Get();
                    Child->X=NextWidgetX;
                    NextWidgetX-=_Spacing;
                }
                break;
            }
            
            case EHorizontalPositionerAlign::Center:
            {
                float SelfWith=PresentSize.X/GetAccumulatedScale().X;

                //计算可见子控件的总长度
                float VisibleLength=.0f;
                for(int32_t i=MinVisibleSubWidgetIndex;i<=MaxVisibleSubWidgetIndex;++i)
                {
                    VisibleLength+=ChildWidths[i]+_Spacing;
                }
                if(ChildWidths.Num()>0)
                {
                    VisibleLength-=_Spacing;
                }

                float NextWidgetX=(SelfWith-VisibleLength)/2;
                for(int32_t i=MinVisibleSubWidgetIndex;i<=MaxVisibleSubWidgetIndex;++i)
                {
                    auto& Child=SubWidgets[i];
                    Child->X=NextWidgetX;
                    NextWidgetX+=Child->Width.Get()+_Spacing;
                }
                break;
            }

            default:
            {
                //不应执行到这里
                assert(false);
            }
        }

         
        //计算子控件的位置和大小
        for(int32_t i=MinVisibleSubWidgetIndex;i<=MaxVisibleSubWidgetIndex;++i)
        {
            auto& Child=SubWidgets[i];
            Child->CalculatePresentPositionAndSize();
        }

    }


    OnChildrenArranged.ExecuteIfBound();
}

void RHorizontalPositionerWidget::PaintSubWidgets(uint16_t &InZOrder)
{   
    if(!HasVisibleSubWidget)
    {
        return;
    }

    for(int32_t i=MinVisibleSubWidgetIndex;i<=MaxVisibleSubWidgetIndex;++i)
    {
        auto& Child=SubWidgets[i];
        Child->Paint(InZOrder);
    }
}
